#ifndef GL_DRAWER_HPP
#define GL_DRAWER_HPP

#include "gl_data.hpp"
#include "thrid.hpp"
#include "mouse_trans.hpp"
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>

static const char* vertexShaderSource =
"attribute highp vec3 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
"  col=colAttr;\n"
"  gl_Position=matrix * vec4(posAttr,1.0f);\n"
"}\n";

static const char* fragmentShaderSource =
"varying lowp vec4 col;\n"
"void main() {\n"
"   gl_FragColor = col;\n"
"}\n";

typedef std::map<std::string, std::shared_ptr<GLData>> GLDataMap;

class GLDrawer : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
    Q_OBJECT
public:
    GLDrawer(QWidget* parent = nullptr,
        QString file_vert_src_="",
        QString file_frag_src_="");

    ~GLDrawer();

    void clear_data();
    void start_timer();
    void normalize(const float scale = 0.5);
    void clear_data(const std::string& key);
    void add_data(std::shared_ptr<GLData>& data);
    void set_color_bg(const float color[4]);
    void set_point_size(const int point_size_);
protected:
    void paintGL();
    void initializeGL();
    void resizeGL(int w, int h);
private slots:
    void slot_mouse_update();
private:
    QMatrix4x4 matrix;
    MouseTrans* mouse_ts;
    //paint times
    int m_frame;
    //init status
    bool inited;
    //file name of vertices shader
    QString file_vert_src;
    //file name of fragment shader
    QString file_frag_src;
    //max pos record for normalize
    Vec3d pos_max;
    //min pos record for normalize
    Vec3d pos_min;
    //draw data map
    GLDataMap data_map;
    //gl show point size
    int gl_point_size;

    //timer for auto update gl
    QTimer* timer_update;

    //qt opengl
    GLint gl_attr_pos = 0;
    GLint gl_attr_color = 0;
    GLint gl_uniform_matrix = 0;
    QOpenGLShaderProgram* gl_program;

    //view background color
    float bgcolor[4] = { 0.2f, 0.3f, 0.3f, 1.0f };
    //spdlog logger
    std::shared_ptr<spdlog::logger> logger;

    void wheelEvent(QWheelEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);

};

#endif